/**
 * 基于jquery的ajax进行封装。增加以下2个功能
 * 1、ajax提交前统一展示loading或者做其他界面防重复提交的处理。
 * 2、对返回的结果进行统一处理，主要是解决session过期后的提醒
 *    以及其他一些处理，开发者只需要关心业务的处理即可。
 * Created by smit on 2015/11/13.
 *
 *
 * use：
 * 使用方式与jquery的ajax使用方式一致，分别为$.Ajax,$.Post,$.Get,$.GetJson
 * 即：原有jquery的ajax函数名的首字母大写。
 *
 * ex:
 * 通用的ajaxresult的处理。
 * $.Ajax({
     url: 'someUrl',
     data: {},
     container: '.modal-content',
     success: function (r) {
       //成功后的处理
       $userGrid.bootgrid('reload');
       Dialog.success('添加成功');
     },
     error: function (m) {
       //失败后的处理，比如服务端返回500
       Dialog.danger('添加失败，原因：' + m);
     }
  });

 不适用弹出狂提示，并且使用自定义的服务端返回类型：
 $.Ajax({
     url: 'someUrl',
     alert：false, //成功或失败都不进行提示
     defaultResultType:false,//使用自定义的返回对象
     data: {},
     container: '.modal-content',
     success: function (r) {
       //成功后的处理
       $userGrid.bootgrid('reload');
       Dialog.success('添加成功');
     },
     error: function (m) {
       //失败后的处理，比如服务端返回500
       Dialog.danger('添加失败，原因：' + m);
     }
  });
 *
 */

/**
 * 根据回调函数来处理成功方法,由于有时候比如权限或500的时候,服务器是将错误页面传过来,状态为是200。这是时候就需要做特殊处理。
 * @param data
 * @param callback
 */
function handleSuccessByCallback(data, callback) {
    var httpstatus = $(data).filter('input[name="httpstatus"]').val();
    if (httpstatus && httpstatus != 200) {
        handelError(parseInt(httpstatus));
    } else {
        $.isFunction(callback) ? callback(data) : callback;
    }
}
/**
 * 提交之后的处理，主要是响应之后，去除loading效果等处理。
 */
var afterCommit = function (o) {
    var container = o.container;
    if (container) {
        var $container = $(container);
        if ($.isFunction(container)) {
            $container = container();
        }
        $container.loaded();
    }
}

/**
 * 全局异常封装
 * @param event
 * @param XMLHttpRequest
 * @param settings
 */
function onLoadError(event, XMLHttpRequest, settings) {
    afterCommit(settings);
    var text = XMLHttpRequest.responseText;
    var httpStatus;
    try {
        httpStatus = $(text).find('input[name="httpstatus"]').val();
    } catch (e) {
        console.log(e);
    }
    var status = parseInt(httpStatus || XMLHttpRequest.status);
    handelError(status)
};

/**
 * 异常处理
 * @param status
 */
function handelError(status) {
    var msg ='错误码：' + status +' 【${statusText}】';
    if (status === 400) {
        //参数绑定异常，通常是没有通过服务器的有效性验证导致。
        try {
            var bindErrors = JSON.parse(msg); //参见 com.ryi.life.web.controller.AdviceController.processValidationError()。
            if ($.isArray(bindErrors)) {
                var str = "<p>参数绑定错误：<p>";
                $.each(bindErrors, function (i, error) {
                    var fieldText = $('input[name="' + error.field + '"]').parent().prev().text();
                    if (fieldText) {
                        fieldText = fieldText.replace("*", ""); //去掉必填项的*号。
                    }
                    //error对象参见org.springframework.validation.FieldError
                    str += "<p>" + fieldText + " " + error.defaultMessage + "</p>";
                });
                msg = str;
            }
        } catch (e) {
            console.error(e);
            msg = "系统错误";
        }
        _e(msg, o);
    } else if (status === 401) {
        //弹出超时
        msg = msg.replace('${statusText}', "会话已超时,请重新登录！");
        Dialog.warning(msg)
        // setTimeout(function () {
        //     window.top.location.href = ROOT_PATH + "logout";
        // },2000)
    } else if (status === 403) {
        //弹出层提示没有权限。
        msg = msg.replace('${statusText}', "对不起，您没有权限访问该功能！");
        Dialog.danger(msg);
    } else if (status === 404) {
        //弹出层提示找不到资源。
        msg = msg.replace('${statusText}', "对不起，没有找到资源！");
        Dialog.danger(msg);
    } else if (status === 500 || status > 400) {
        //服务器端发生错误
        msg = msg.replace('${statusText}', "系统出现了一个未指明的错误。");
        Dialog.danger(msg);
    }
}

//通用的ajax错误提示
$(document).ajaxError(onLoadError);

(function ($) {

    var _s = null;
    var _e = null;


    /**
     * 通用的error时的处理
     */
    var e = function (msg, o) {
        if (o.alert) {
            Dialog.danger(msg || "系统错误，请联系管理员");
        }
    }

    var defaults = {
        type: 'post',
        dataType: 'json',
        async: true,
        alert: true, //不弹出消息
        container: null, //dom容器，如果有值，则会在该dom上显示loading效果，
        loadingMsg: null,
        defaultResultType: true //是否使用默认的服务端返回的结果内容。默认使用的com.ryi.life.web.model.AjaxResult
    }

    /**
     * @see $.ajax
     */
    var Ajax = function (o) {
        o = $.extend({}, defaults, o);

        _s = o.success || function () {
        };
        _e = o.error || e;
        o.success = function (_r, status, request) {
            afterCommit(o);
            if (o.defaultResultType) {
                if (_r.success) {
                    _s(_r.data);
                } else {
                    e(_r.message, o)
                }
            } else {
                _s(_r);
            }
        };

        beforeCommit(o);
        $.ajax(o);
    };

    /**
     * @see $.get
     */
    var Get = function (url, data, callback) {
        if ($.isFunction(data)) {
            callback = data;
            data = undefined;
        }
        $.get(url, data).done(function (_r) {
            handleSuccessByCallback(_r, callback);
        });
    }


    /**
     *
     * @see $.post
     */
    var Post = function (url, data, callback) {
        if ($.isFunction(data)) {
            callback = data;
            data = undefined;
        }
        $.post(url, data, function (_r) {
            handleSuccessByCallback(_r, callback);
        })
    }

    /**
     * @see $.getJSON
     */
    var GetJSON = function (url, data, callback) {
        if ($.isFunction(data)) {
            callback = data;
            data = undefined;
        }
        $.getJSON(url, data).done(function (_r) {
            handleSuccessByCallback(_r, callback);
        });
    }

    /**
     * 提交之前的处理，只要是增加loading效果等。
     */
    var beforeCommit = function (o) {
        var container = o.container;
        if (container) {
            var $container = $(container);
            if ($.isFunction(container)) {
                $container = container();
            }
            $container.loading(o.loadingMsg);
        }
    }

    $.extend({
        Ajax: Ajax,
        Get: Get,
        Post: Post,
        GetJSON: GetJSON
    });
})(jQuery);


